﻿using LJ.Abstractions.Exceptions;
using LJ.EventBus.Abstractions;
using LJ.EventBus.FastDog.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LJ.EventBus.FastDog.Internal;

public class EventHandlerInvoker(IServiceScopeFactory serviceScopeFactory,  IEventHandlerManager eventHandlerManager) : IEventHandlerInvoker
{
    private readonly IServiceScopeFactory _serviceScopeFactory = serviceScopeFactory;
    private readonly IEventHandlerManager _eventHandlerManager = eventHandlerManager;

    public async Task InvokeAsync(Message message)
    {
        var eventHandlerDescriptor = _eventHandlerManager.GetEventHandlerDescriptor(message.GetName());

        using var scope = _serviceScopeFactory.CreateScope();
        var eventHandlerInstance =
            scope.ServiceProvider.GetRequiredService(eventHandlerDescriptor.EventHandlerType);

        var method = eventHandlerDescriptor.EventHandlerType.GetMethod("ExecuteAsync",
                [eventHandlerDescriptor.EventType, typeof(IDictionary<string, string>)]);

        var task = (Task?)method!.Invoke(eventHandlerInstance, [message.Value, message.Headers]);
        await task!.ConfigureAwait(false);
    }
}
